<?php

namespace app\common\model\marketing;

use addons\xyb\XypHelper;
use app\api\model\xyb\Order;
use app\common\model\points_mall\Orders;
use think\Db;
use think\Exception;
use think\Log;
use think\Model;


class UsersMarketingCoupons extends Model
{

    // 表名
    protected $name = 'users_marketing_coupons';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    public static function getUsersAdminLists(){
        $keyword = request()->param('keyword', '');
        $type = request()->param('type/a');
        $deadline_time = request()->param('deadline_time/a');
        $create_time = request()->param('createtime/a');
        $grant_platform = request()->param('grant_platform');
        $use_platform = (int)request()->param('use_platform');
        $use_status = (int)request()->param('use_status');
        $field = 'user_coupons.id,user_coupons.order_id,user_coupons.use_platform,user_coupons.type,user_coupons.user_id,
        user_coupons.deadline_time,user_coupons.use_status,user_coupons.use_time,user_coupons.discount_amount,
        user_coupons.createtime,marketing_coupons.name,user_coupons.order_amount';
        $query = self::alias('user_coupons')
            ->field($field)
            ->join('marketing_coupons', 'user_coupons.coupons_id=marketing_coupons.id')
        ->where('user_coupons.grant_status', 1);
        if ($keyword) {
            $query->where(function ($query) use ($keyword) {
                $query->where('user_coupons.id', 'like', "%{$keyword}%")
                    ->whereOr('user_coupons.order_id', 'like', "%{$keyword}%")
                    ->whereOr('user_coupons.user_id', 'like', "%{$keyword}%")
                    ->whereOr('marketing_coupons.name', 'like', "%{$keyword}%");
            });
        }
        if ($type = XypHelper::stringToArray($type)) {
            $query->whereIn('user_coupons.type', $type);
        }
        if ( $use_platform ) {
            $query->where('user_coupons.use_platform', $use_platform);
        }

//        if (in_array($use_status, [0, 1])) {
//            $query->where('user_coupons.use_status', $use_status);
//        }
        if ($deadline_time = XypHelper::stringToArray($deadline_time)) {
            $query->whereBetween('user_coupons.deadline_time', [XypHelper::getTimestamp($deadline_time[0]), XypHelper::getTimestamp($deadline_time[1])]);
        }
        if ($create_time = XypHelper::stringToArray($create_time)) {
            $query->whereBetween('user_coupons.createtime', [XypHelper::getTimestamp($create_time[0]), XypHelper::getTimestamp($create_time[1])]);
        }
        $lists = $query->order('user_coupons.id desc')->paginate(10);
        return $lists;
    }

    public static function removeUsersCoupons($coupons_id){
        $coupons_id = XypHelper::stringToArray($coupons_id);
        try {
            self::whereIn('id', $coupons_id)->update(['grant_status' => 0, 'updatetime'=>time()]);
            return true;
        } catch (\Exception $e) {
            return false;
        }
    }

    public static function getCouponsUsersReceiveTotal($user_id, $coupons_id)
    {
        return self::where('user_id', $user_id)->where('coupons_id', $coupons_id)->count();
    }

    public static function getCouponsUsersReceiveInfo($user_id, $coupons_id)
    {
        return self::where('user_id', $user_id)->where('coupons_id', $coupons_id)->find();
    }

    public static function getUsersCouponsInfo($user_id, $coupons_id)
    {
        return self::where('id', $coupons_id)->where('user_id', $user_id)->find();
    }

    public static function usersReceiveCoupons($user_id, $coupons)
    {

        try {
            Db::startTrans();
            if ($coupons['expiration_method'] == 1) {
                $deadline_time = $coupons['use_end_time'];
            } else {
                $deadline_time = time() + ($coupons['effective_days'] * 3600);
            }
//        if($deadline_time > $coupons['use_end_time']){
//            $deadline_time = $coupons['use_end_time'];
//        }
            $forms = [
                'user_id' => $user_id,
                'coupons_id' => $coupons['id'],
                'use_platform' => 0,
                'deadline_time' => $deadline_time,
                'type' => $coupons['type'],
                'grant_status' => 1,
                'use_status' => 0,
            ];
            $res = self::create($forms);
            if (!$res) {
                Db::rollback();
                return false;
            }

            MarketingCoupons::where('id', $coupons['id'])->setInc('receive_total', 1);
            Db::commit();
            return true;
        } catch (\Exception $e) {
            var_dump($e);
            Db::rollback();
            return false;
        }
    }

    public static function usersJobsReceiveCoupons($user_id, $coupons, $source = 1, $attach = [])
    {
        try {
            $deadline_time = 0;
            if ($coupons['expiration_method'] == 1) {
                $deadline_time = $coupons['use_end_time'];
            } else {
                $deadline_time = time() + ($coupons['effective_days'] * 3600);
            }
//        if($deadline_time > $coupons['use_end_time']){
//            $deadline_time = $coupons['use_end_time'];
//        }
            $forms = [
                'user_id' => $user_id,
                'coupons_id' => $coupons['id'],
                'use_platform' => 0,
                'deadline_time' => $deadline_time,
                'type' => $coupons['type'],
                'grant_status' => 1,
                'use_status' => 0,
                'source'     => $source,
                'attach'    => XypHelper::formatArrayToString($attach),
            ];
            $res = self::create($forms);
            if (!$res || !isset($res->id) || !$res->id) {
                return false;
            }
            MarketingCoupons::where('id', $coupons['id'])->setInc('receive_total', 1);
            return $res->id;
        } catch (\Exception $e) {
            Db::rollback();
            return false;
        }
    }
    public static function getUsersUsableCoupons($users_id, $amount, $grant_platform, $errand_method, $business_id, $product_id,$is_show_amount = false)
    {
        $coupons_ids = self::where('user_id', $users_id)
            ->where('use_status', 0)
            ->where('grant_status', 1)
            ->where('deadline_time', '>', time())
            ->column('coupons_id');
        if (!$coupons_ids) {
            return [];
        }
        $field = 'id,name,amount,type,satisfy_amount,discount_rate,get_limit,effective_days,
        expiration_method,describe,random_rule,grant_errand_method,grant_ticket_method,receive_total,grant_total,
        grant_ticket_business_id,grant_ticket_product_id,grant_platform,use_start_time,use_end_time';
        $query = MarketingCoupons::field($field)->whereIn('grant_status', [2, 3])
            ->whereIn('id', $coupons_ids)
            ->whereIn('grant_platform', [1, $grant_platform]);
        if ($grant_platform == 2 && $errand_method) {
           // $errand_method += 1;
            $query->where(function ($query) use ($grant_platform, $errand_method) {
                $query->whereIn('grant_errand_method', [1, intval($errand_method)]);
            });
        }
        if ($grant_platform == 3 && $business_id && $product_id) {
            $query->where(function ($query) use ($grant_platform, $business_id, $product_id) {
                $query->where("grant_ticket_method", 1)
                    ->whereOr(function ($q) use ($business_id) {
                        $q->whereRaw("FIND_IN_SET('{$business_id}', grant_ticket_business_id)");
                    })->whereOr(function ($q) use ($product_id) {
                        $q->whereRaw("FIND_IN_SET('{$product_id}', grant_ticket_product_id)");
                    });
            });
        }

        $lists = $query->order('id desc')->select();
        if (!$lists) {
            return [];
        }
        $lists_maps = [];
        foreach ($lists as $k => $v) {
            $use_status = false;
            $use_msg = '满'.floatval($v['satisfy_amount']).'元可用';
            if($v['satisfy_amount'] && ($amount >= (float)$v['satisfy_amount'] )){
                $use_status = true;
            }
            if($v['expiration_method'] == 1){
                if($v['use_start_time'] > time() || $v['use_end_time'] < time()){
                    $use_status = false;
                    $use_msg = date('Y.m.d', $v['use_start_time']).'后可使用';
                }
            }
            $coupons_amount = self::_getCouponsAmount($amount, $v);
            if($v['type'] == 4 && $v['random_rule'] && (bool)$is_show_amount == true){
                $use_amount = self::where('coupons_id', $v['id'])->where('use_status', 1)->sum('discount_amount');
                if($use_amount > $v['amount']){
                    unset($lists[$v]);continue;
                }
                $random_discount = XypHelper::getRandomDiscount($v['random_rule']);
                if($random_discount){
                    $coupons_amount['discount_amount'] = (float)sprintf('%.2f', $random_discount);
                    $coupons_amount['real_amount'] = (float)sprintf('%.2f', (float)$amount - $random_discount);
                }
            }
            if($users_coupons = UsersMarketingCoupons::getCouponsUsersReceiveInfo($users_id, $v['id'])){
                $v['deadline_time'] = $users_coupons['deadline_time'];
            } else {
                if($v['receive_total'] >= $v['grant_total']){
                    continue;
                }
            }
            $lists_maps[$k] = [
                'id' => $v['id'],
                'name' => $v['name'],
                'type_text' => MarketingCoupons::getTypeList($v['type']),
                'type' => $v['type'],
                'get_limit' => $v['get_limit'],
                'discount_rate' => $v['discount_rate'],
                'satisfy_amount' => $v['satisfy_amount'],
                'amount' => $v['amount'],
                'describe' => $v['describe'],
                'grant_platform' => $v['grant_platform'],
                'coupons_amount' => $coupons_amount,
                'coupons_text' => MarketingCoupons::getCouponsAmountMsg($v),
                'platform_text' => MarketingCoupons::getGrantPlatformList($v),
                'usage_text' => MarketingCoupons::getCouponsGrantMethodMsg($v),
                'deadline_text' => MarketingCoupons::getExpirationMsg($v),
                'deadline_stated_arr' => MarketingCoupons::getCouponsExpirationMsg($v),
                'amount_text' => MarketingCoupons::getAmountTipsMsg($v),
                'use_status_text' => ['status'=> $use_status, 'msg' => $use_msg]
            ];
        }
        return $lists_maps;
    }

    public static function getUsersCouponsPaymentCanBeUsed($users_id, $amount, $coupons_id, $grant_platform, $errand_method = 0, $business_id = 0, $product_id = 0)
    {
        $user_coupons = self::where('user_id', $users_id)->where('coupons_id', $coupons_id)
            ->where('use_status', 0)
            ->where('grant_status', 1)
            ->where('deadline_time', '>', time())
        //    ->whereIn('use_platform', [1, $grant_platform])
            ->find();
        if (!$user_coupons) {
            return [];
        }
        $field = 'id,name,amount,type,satisfy_amount,discount_rate,get_limit,effective_date,effective_days,
        expiration_method,describe,grant_platform,random_rule';
        $query = MarketingCoupons::field($field)->whereIn('id', $coupons_id)
            ->whereIn('grant_status', [2, 3])
            ->whereIn('grant_platform', [1, $grant_platform]);
        if ($grant_platform == 2 && $errand_method) {
            $query->where(function ($query) use ($grant_platform, $errand_method) {
                $query->whereIn('grant_errand_method', [1, intval($errand_method)]);
            });
        }
        if ($grant_platform == 3 && $business_id && $product_id) {
            $query->where(function ($query) use ($grant_platform, $business_id, $product_id) {
                $query->where("grant_ticket_method", 1)
                    ->whereOr(function ($q) use ($business_id) {
                        $q->whereRaw("FIND_IN_SET('{$business_id}', grant_ticket_business_id)");
                    })->whereOr(function ($q) use ($product_id) {
                        $q->whereRaw("FIND_IN_SET('{$product_id}', grant_ticket_product_id)");
                    });
            });
        }
        if ($amount) {
            $query->where(function ($query) use ($amount) {
                $query->where('satisfy_amount', 0)->whereOr(function ($q) use ($amount) {
                    $q->where('satisfy_amount', '>', 0)->where('satisfy_amount', '<=', floatval($amount));
                });
            });
        }
        if (!$details = $query->find()) {
            return [];
        }
        $coupons_amount = self::_getCouponsAmount($amount, $details);
        $user_coupons->discount_amount = $coupons_amount['discount_amount'];
        $user_coupons->real_amount = $coupons_amount['real_amount'];
        $user_coupons->favourable = $coupons_amount['favourable'];
        /*立减劵*/
        if($details['type'] == 4 && $details['random_rule']){
            $user_coupons->discount_amount = 0.01;
            $user_coupons->real_amount = (float)$amount;
            $random_discount = XypHelper::getRandomDiscount($details['random_rule']);
            if($random_discount){
                $user_coupons->discount_amount = (float)sprintf('%.2f', $random_discount);
                $user_coupons->real_amount = (float)sprintf('%.2f', (float)$amount - $random_discount);
            }
        }
        return $user_coupons;
    }

    public static function getUsersCouponsCanBeUsed($users_id, $amount, $coupons_id, $grant_platform, $errand_method = 0, $business_id = 0, $product_id = 0)
    {
        $user_coupons = self::where('user_id', $users_id)->where('coupons_id', $coupons_id)
            ->where('use_status', 0)
            ->where('grant_status', 1)
            ->where('deadline_time', '>', time())
            ->whereIn('use_platform', [1, $grant_platform])
            ->find();
        if (!$user_coupons) {
            return [];
        }
        $field = 'id,name,amount,type,satisfy_amount,discount_rate,get_limit,effective_date,effective_days,
        expiration_method,describe,grant_platform';
        $query = MarketingCoupons::field($field)   ->whereIn('grant_status', [2, 3])->whereIn('id', $coupons_id)
            ->whereIn('grant_platform', [1, $grant_platform]);
        if ($grant_platform == 2 && $errand_method) {
            $query->where(function ($query) use ($grant_platform, $errand_method) {
                $query->whereIn('grant_errand_method', [1, intval($errand_method)]);
            });
        }
        if ($grant_platform == 3 && $business_id && $product_id) {
            $query->where(function ($query) use ($grant_platform, $business_id, $product_id) {
                $query->where("grant_ticket_method", 1)
                    ->whereOr(function ($q) use ($business_id) {
                        $q->whereRaw("FIND_IN_SET('{$business_id}', grant_ticket_business_id)");
                    })->whereOr(function ($q) use ($product_id) {
                        $q->whereRaw("FIND_IN_SET('{$product_id}', grant_ticket_product_id)");
                    });
            });
        }
        if ($amount) {
            $query->where(function ($query) use ($amount) {
                $query->where('satisfy_amount', 0)->whereOr(function ($q) use ($amount) {
                    $q->where('satisfy_amount', '>', 0)->where('satisfy_amount', '<=', floatval($amount));
                });
            });
        }
        if (!$details = $query->find()) {
            return [];
        }
        $coupons_amount = self::_getCouponsAmount($amount, $details);
        $user_coupons->discount_amount = $coupons_amount['discount_amount'];
        $user_coupons->real_amount = $coupons_amount['real_amount'];
        $user_coupons->favourable = $coupons_amount['favourable'];
        return $user_coupons;
    }

    public static function usersUsedCoupons($users_id, $coupons_id, $order_id = 0, $discount = 0, $use_platform = 2, $order_amount = 0)
    {
        $user_coupons = self::where('id', $coupons_id)->where('user_id', $users_id)
            ->where('use_status', 0)->where('grant_status', 1)->find();
        if (!$user_coupons) {
            return false;
        }
        $user_coupons->use_status = 1;
        $user_coupons->use_time = time();
        $user_coupons->order_id = $order_id;
        $user_coupons->use_platform = $use_platform;
        $user_coupons->discount_amount = $discount;
        $user_coupons->order_amount = $order_amount;
        $res = $user_coupons->save();
        if (!$res) {
            return false;
        }
        MarketingCoupons::where('id', $user_coupons->coupons_id)->setInc('use_total');
        /*兑换来的*/
        if($user_coupons->attach && $user_coupons->source == 3){
            Orders::setOrdersPaymentUses($user_coupons->attach);

        }
        return true;
    }

    public static function returnUsersCoupons($users_id, $coupons_id, $order_id)
    {
        $user_coupons = self::where('user_id', $users_id)->where('id', $coupons_id)
            ->where('use_status', 1)->where('order_id', $order_id)->find();

        if (!$user_coupons) {
            return false;
        }
        $is_return = (int)MarketingCoupons::where('id', $user_coupons->coupons_id)->value('is_return');
        if($is_return === 2){
            return true;
        }
        $user_coupons->use_status = 0;
        $user_coupons->use_time = 0;
        $user_coupons->order_id = 0;
        $user_coupons->updatetime = time();
        $res = $user_coupons->save();
        if (!$res) {
            return false;
        }
        MarketingCoupons::where('id', $user_coupons->coupons_id)->setDec('use_total');
        return true;
    }

    public static function getUsersCouponsDetails($coupons_id)
    {
        $user_coupons = self::where('id', $coupons_id)->find();
        if (!$user_coupons) {
            return false;
        }
        $marketing_coupons = MarketingCoupons::where('id', $user_coupons->coupons_id)->find();
        if (!$marketing_coupons) {
            return false;
        }
        $lists_maps = [
            'id' => $marketing_coupons['id'],
            'name' => $marketing_coupons['name'],
            'type_text' => MarketingCoupons::getTypeList($marketing_coupons['type']),
            'type' => $marketing_coupons['type'],
            'get_limit' => $marketing_coupons['get_limit'],
            'discount_rate' => $marketing_coupons['discount_rate'],
            'satisfy_amount' => $marketing_coupons['satisfy_amount'],
            'marketing_coupons' => $marketing_coupons,
            'amount' => $marketing_coupons['amount'],
            'describe' => $marketing_coupons['describe'],
            'coupons_text' => MarketingCoupons::getCouponsAmountMsg($marketing_coupons),
            'platform_text' => MarketingCoupons::getGrantPlatformList($marketing_coupons),
            'usage_text' => MarketingCoupons::getCouponsGrantMethodMsg($marketing_coupons),
            'grant_platform' => $marketing_coupons['grant_platform'],
            'deadline_text' => MarketingCoupons::getExpirationMsg($marketing_coupons),
            'amount_text' => MarketingCoupons::getAmountTipsMsg($marketing_coupons)
        ];
        return $lists_maps;
    }

    public static function _getCouponsAmount($amount, $coupons)
    {
        $amount = floatval($amount);
        $response = [
            'amount' => $amount,
            'favourable' => 0,//折扣价格
            'real_amount' => 0,//优惠金额
            'discount_amount' => 0
        ];
        if ($coupons['type'] == 3) {
            $response['favourable'] = (float)sprintf('%.2f', $coupons['discount_rate'] / 10);
            $response['real_amount'] = (float)sprintf('%.2f', ($amount * $response['favourable']));
            $response['discount_amount'] = (float)sprintf('%.2f', ($amount - $response['real_amount']));
        } else if ($coupons['type'] == 4) {
            $response['favourable'] = (float)sprintf('%.2f', $coupons['amount']);
            $response['discount_amount'] = '随机减';
            $response['real_amount'] = (float)sprintf('%.2f', ($amount));
        } else {
            $response['favourable'] = (float)sprintf('%.2f', $coupons['amount']);
            $response['discount_amount'] = (float)sprintf('%.2f', $coupons['amount']);
            $response['real_amount'] = (float)sprintf('%.2f', ($amount - $response['discount_amount']));
        }
        return $response;
    }


    public static function getUsersCouponsLonelyCanBeUsed($users_id, $amount, $coupons_id, $grant_platform, $errand_method = 0, $business_id = 0, $product_id = 0)
    {
        $user_coupons = self::where('user_id', $users_id)->where('coupons_id', $coupons_id)
            ->where('use_status', 0)
            ->where('grant_status', 1)
            ->where('deadline_time', '>', time())
            ->whereIn('use_platform', [1, $grant_platform])
            ->find();
        if (!$user_coupons) {
            return [];
        }
        $field = 'id,name,amount,type,satisfy_amount,discount_rate,get_limit,effective_date,effective_days,
        expiration_method,describe,grant_platform,random_rule';
        $query = MarketingCoupons::field($field)   ->whereIn('grant_status', [2, 3])->whereIn('id', $coupons_id)
            ->whereIn('grant_platform', [1, $grant_platform]);
        if ($grant_platform == 2 && $errand_method) {
            $query->where(function ($query) use ($grant_platform, $errand_method) {
                $query->whereIn('grant_errand_method', [1, intval($errand_method)]);
            });
        }
        if ($grant_platform == 3 && $business_id && $product_id) {
            $query->where(function ($query) use ($grant_platform, $business_id, $product_id) {
                $query->where("grant_ticket_method", 1)
                    ->whereOr(function ($q) use ($business_id) {
                        $q->whereRaw("FIND_IN_SET('{$business_id}', grant_ticket_business_id)");
                    })->whereOr(function ($q) use ($product_id) {
                        $q->whereRaw("FIND_IN_SET('{$product_id}', grant_ticket_product_id)");
                    });
            });
        }
        if (!$details = $query->find()) {
            return [];
        }

        /*立减劵*/
        if($details['type'] == 4 && $details['random_rule']){
            $user_coupons->discount_amount = 0.01;
            $user_coupons->real_amount = (float)$amount;
            $random_discount = XypHelper::getRandomDiscount($details['random_rule']);
            if($random_discount){
                $user_coupons->discount_amount = (float)sprintf('%.2f', $random_discount);
                $user_coupons->real_amount = (float)sprintf('%.2f', (float)$amount - $random_discount);
            }
        }
        return $user_coupons;
    }

    public static function getUsersCouponsSourceTotal($users_id, $source = 2, $use_status = 0)
    {
        $query = self::where('user_id', $users_id)->where('source', $source);
        if ($use_status  == 1) {
            $query->where('use_status', ($use_status - 1));
        }
        return (int)$query->count('id');
    }

    public static function getUsersCouponsSourceLists($users_id, $source = 2, $use_status = 0)
     {
         $coupons_ids = self::where('user_id', $users_id)
             ->where('use_status', 0)
             ->where('grant_status', 1)
             ->where('source', $source)
             ->where('deadline_time', '>', time())
             ->column('coupons_id');
         if (!$coupons_ids) {
             return [
                 'total' => 0,
                 'per_page'=>15,
                 'current_page'=>1,
                 'last_page'=>0,
                 'data' => []
             ];
         }
         $field = 'id,name,amount,type,satisfy_amount,discount_rate,get_limit,effective_days,
    expiration_method,describe,random_rule,grant_errand_method,grant_ticket_method,receive_total,grant_total,
    grant_ticket_business_id,grant_ticket_product_id,grant_platform,use_start_time,use_end_time';
         $query = MarketingCoupons::field($field)->whereIn('id', $coupons_ids);

         $lists = $query->order('id desc')->paginate();
         if (!$lists->items()) {
             return [];
         }
         $lists_maps = [];
         foreach ($lists->items() as $k => $v) {
             $use_msg = '满'.floatval($v['satisfy_amount']).'元可用';

             if($v['expiration_method'] == 1){
                 if($v['use_start_time'] > time() || $v['use_end_time'] < time()){
                     $use_status = false;
                     $use_msg = date('Y.m.d', $v['use_start_time']).'后可使用';
                 }
             }
             $coupons_amount = self::_getCouponsAmount(0, $v);
             $lists_maps[$k] = [
                 'id' => $v['id'],
                 'name' => $v['name'],
                 'type_text' => MarketingCoupons::getTypeList($v['type']),
                 'type' => $v['type'],
                 'get_limit' => $v['get_limit'],
                 'discount_rate' => $v['discount_rate'],
                 'satisfy_amount' => $v['satisfy_amount'],
                 'amount' => $v['amount'],
                 'describe' => $v['describe'],
                 'grant_platform' => $v['grant_platform'],
                 'coupons_amount' => $coupons_amount,
                 'coupons_text' => MarketingCoupons::getCouponsAmountMsg($v),
                 'platform_text' => MarketingCoupons::getGrantPlatformList($v),
                 'usage_text' => MarketingCoupons::getCouponsGrantMethodMsg($v),
                 'deadline_text' => MarketingCoupons::getExpirationMsg($v),
                 'deadline_stated_arr' => MarketingCoupons::getCouponsExpirationMsg($v),
                 'amount_text' => MarketingCoupons::getAmountTipsMsg($v),
                 'use_status_text' => ['status'=> $use_status, 'msg' => $use_msg]
             ];
         }
         return [
             'total' => $lists->total(),
             'per_page'=>15,
             'current_page'=>$lists->currentPage(),
             'last_page'=>$lists->lastPage(),
             'data' => $lists_maps
         ];
     }
}
